using System.Net;
using System.Security.Claims;
using EagCentralPlatform.Net8.Filter;
using KL.Core.Common.Utils;
using KL.Standard.Core.Converter;
using KL.Standard.Model.Infrastructure;
using KL.Standard.Model.Models.BaseArch;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Minio;
using Minio.DataModel.Args;
using Newtonsoft.Json;

namespace EagCentralPlatform.Net8.Controllers;

[Authorize]
[ServiceFilter(typeof(LogFilterAttribute))]
//[EnableCors("any")]
//[ServiceFilter(typeof(LogFilterAttribute))]
public class BaseApiController : ControllerBase
{
    //protected ILog _log = null;
    //public ILogger<BaseApiController> _log { set; get; }

    public BaseApiController()
    {
        //_log = KLHttpContext.Current.RequestServices.GetService<ILogger<BaseApiController>>();
        //_log = LogManager.GetLogger(this.GetType());
    }

    #region  获取当前用户信息(loginV1版本对应的获取用户信息)
    /// <summary>
    /// 获取当前用户信息(loginV1版本对应的获取用户信息)
    /// </summary>
    /// <returns></returns>
    [Obsolete]
    protected CurUserInfo GetCurUserInfo2()
    {
        string loginID = User.FindFirst(d => d.Type == ClaimTypes.Name)?.Value;
        string idStr = User.FindFirst(d => d.Type == ClaimTypes.Sid)?.Value;
        string roleStr = User.FindFirst(d => d.Type == ClaimTypes.Role)?.Value;
        string deptCode = User.FindFirst(d => d.Type == ClaimTypes.GroupSid)?.Value;
        string companyCode = User.FindFirst(d => d.Type == ClaimTypes.Country)?.Value;
        string isSystemStr = User.FindFirst(d => d.Type == ClaimTypes.Actor)?.Value;
        return new CurUserInfo()
        {
            id = string.IsNullOrEmpty(idStr) ? 0 : long.Parse(idStr),
            loginID = loginID,
            roleID = string.IsNullOrEmpty(roleStr) ? 0 : long.Parse(roleStr),
            deptCode = deptCode,
            companyCode = companyCode,
            isSystem = Int32.Parse(isSystemStr)
        };
        //return Request.Properties["CurUserInfo"] as CurUserInfo;
        //return null;
    }
    #endregion

    #region  获取当前用户信息(loginV2对应获取用户信息)
    /// <summary>
    /// 获取当前用户信息(loginV2对应获取用户信息)
    /// </summary>
    /// <returns></returns>
    protected CurUserInfo GetCurUserInfo()
    {
        return ClaimUtils.GetInfo4Claims<CurUserInfo>(User);
        
    }
    #endregion
    
    #region  获取当前用户信息(loginV3对应获取用户信息)
    /// <summary>
    /// 获取当前用户信息(loginV3对应获取用户信息)
    /// </summary>
    /// <returns></returns>
    protected void GetCurUserInfo2(CurUserInfo userInfo)
    {
        ClaimUtils.GetInfo4Claims<CurUserInfo>(User,userInfo);
    }
    #endregion

    #region 格式输出 主要针对 比如SYS_ID输出时还能SYS_ID
    /// <summary>
    /// 格式输出 主要针对 比如SYS_ID输出时还能SYS_ID
    /// </summary>
    /// <param name="resultObj"></param>
    /// <param name="ignorDefaultValue">是否忽略默认值的输出 即是 null 或者 0 是否不输出</param>
    /// <returns></returns>
    protected IActionResult ReturnActionResult(object resultObj, bool ignorDefaultValue = true)
    {
        var jr = new JsonResult(resultObj);
        JsonSerializerSettings jsetting = new JsonSerializerSettings();
        jsetting.ContractResolver = new KLJsonContractResolver();
        if (ignorDefaultValue)
            jsetting.DefaultValueHandling = DefaultValueHandling.Ignore;
        jr.SerializerSettings = jsetting;
        jr.ContentType = "application/json; charset=utf-8";
        return jr;
    }
    #endregion
    
     #region 保存在本地的文件系统中

    /// <summary>
    /// 保存在本地的文件系统中
    /// </summary>
    /// <param name="loginID">操作人账号</param>
    /// <param name="file">前端上传附件</param>
    /// <param name="rootPath">根目录</param>
    /// <param name="moduleName">模块or表名</param>
    /// <param name="batchId">批号</param>
    /// <returns></returns>
    protected async Task<SysAttachmentPO> SaveAttachment2Local(string loginID, IFormFile file, string rootPath,
        string moduleName, string batchId)
    {
        string processPath =
            $"{rootPath}" +
            $"{Path.DirectorySeparatorChar}Attachment{Path.DirectorySeparatorChar}" +
            $"{moduleName}{Path.DirectorySeparatorChar}" +
            $"{DateTime.Now.ToString("yyyyMMdd")}";
        if (!Directory.Exists(processPath))
        {
            Directory.CreateDirectory(processPath);
        }

        //后缀名
        string fileExt = file.FileName.Substring(file.FileName.LastIndexOf("."));
        string newFileName = $"{(Guid.NewGuid().ToString())}{fileExt}";

        var filePath = $"{processPath}{Path.DirectorySeparatorChar}{newFileName}";
        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        var attachmentPo = new SysAttachmentPO()
        {
            dataTable = moduleName,
            attachType = file.ContentType,
            fileName = file.FileName.Replace(fileExt, ""),
            fileSuffix = fileExt.Replace(".", ""),
            webUrl = "/Attachment/" + DateTime.Now.ToString("yyyyMMdd") + "/" + newFileName,
            realFileName = newFileName,
            phyAddress = filePath,
            creatorID = loginID,
            createdTime = DateTime.Now,
            bldBatchID = batchId,
            //mainID = uID
        };
        return attachmentPo;

    }

    #endregion


    #region 保存在本地的MinIO中

    /// <summary>
    /// 保存在本地的MinIO中
    /// </summary>
    /// <param name="loginID">操作人账号</param>
    /// <param name="file">前端上传附件</param>
    /// <param name="moduleName">模块or表名</param>
    /// <param name="batchId">批号</param>
    /// <returns></returns>
    protected async Task<SysAttachmentPO> SaveAttachment2MinIO(IServiceProvider provider, string bucketName,
        string loginID, IFormFile file, string moduleName, string batchId)
    {
        using (var scope = provider.CreateScope())
        {
            string newObjectName =
                $"/{moduleName}/" +
                $"{DateTime.Now.ToString("yyyyMMdd")}";
            string fileExt = file.FileName.Substring(file.FileName.LastIndexOf("."));
            string newFileName = $"{(Guid.NewGuid().ToString())}{fileExt}";

            newObjectName = $"{newObjectName}/{newFileName}";
            var minioClient = scope.ServiceProvider.GetService<IMinioClient>();
            // using (var stream = new MemoryStream())
            // {
            // await file.CopyToAsync(stream);
            // stream.Position = 0;
            var putObjectArgs = new PutObjectArgs()
                    .WithBucket(bucketName)
                    .WithObject(newObjectName)
                    .WithObjectSize(file.OpenReadStream().Length)
                    .WithStreamData(file.OpenReadStream())
                ;

            var minIoResponse = await minioClient.PutObjectAsync(putObjectArgs);
            if (minIoResponse.ResponseStatusCode == HttpStatusCode.OK)
            {
                var attachmentPo = new SysAttachmentPO()
                {
                    dataTable = moduleName,
                    attachType = file.ContentType,
                    fileName = file.FileName.Replace(fileExt, ""),
                    fileSuffix = fileExt.Replace(".", ""),
                    webUrl = "/Attachment/" + DateTime.Now.ToString("yyyyMMdd") + "/" + newFileName,
                    realFileName = newFileName,
                    creatorID = loginID,
                    createdTime = DateTime.Now,
                    bldBatchID = batchId,
                    bucketName = bucketName,
                    objectName = newObjectName,
                    isSyn = 1,
                    synDt = DateTime.Now,
                    //mainID = uID
                };
                return attachmentPo;
            }

            throw new Exception(
                $"upload minIO server fail, response:[{minIoResponse.ResponseStatusCode}]{minIoResponse.ResponseContent}");
            // }

        }

    }
    #endregion
}